package com.chenfan.mcn.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.mcn.enums.ExcutionApprovalStatusEnum;
import com.chenfan.mcn.extension.Res;
import com.chenfan.mcn.extension.excel.ExcelCustom;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.dto.*;
import com.chenfan.mcn.model.rpc.ChargeClearCallback;
import com.chenfan.mcn.model.rpc.ExcutionOrderChangePaidCallback;
import com.chenfan.mcn.model.rpc.ExcutionOrderPaidCallback;
import com.chenfan.mcn.model.rpc.FinanceExcutionOrderVO;
import com.chenfan.mcn.model.vo.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author tangwei
 * Date:     2021/1/20 11:01
 * Description: 合同执行单
 */
public interface ContractExcutionOrderService {

    /**
     * 批量保存执行单
     *
     * @param excutionOrders          List<ContractExcutionOrder>
     * @param incomeContractAgreement IncomeContractAgreement
     * @param incomeContract          IncomeContract
     */
    void batchSave(List<ContractExcutionOrder> excutionOrders, IncomeContractAgreement incomeContractAgreement, IncomeContract incomeContract);


    /**
     * 批量获取收入合同补充协议下的执行单
     *
     * @param agreementIds
     * @return List<ContractExcutionOrder>
     */
    List<ContractExcutionOrder> getByAgreement(List<Long> agreementIds);

    /**
     * 查询合同下执行单
     *
     * @param incomeContractId
     * @return List<ContractExcutionOrder>
     */
    List<ContractExcutionOrder> getByContractId(Long incomeContractId);

    /**
     * 执行单信息整合数据字典
     *
     * @param excutionOrders
     * @return List<BasicExcutionOrderVO>
     */
    List<BasicExcutionOrderVO> basicExcutionOrderList(List<ContractExcutionOrder> excutionOrders);

    /**
     * 执行单详情
     *
     * @param id
     * @return ExcutionOrderDetailVO {@link ExcutionOrderDetailVO}
     */
    ExcutionOrderDetailVO detail(Long id);

    /**
     * 执行单详情
     *
     * @param excuteCode
     * @return ExcutionOrderDetailVO {@link ExcutionOrderDetailVO}
     */
    PaidInfoDetailVO detailPaidInfoOfCode(String excuteCode);

    /**
     * 执行单编辑
     *
     * @param excutionOrderUpdateDTO
     * @param verifyExcutorAuth
     * @return Integer
     */
    Integer update(ExcutionOrderUpdateDTO excutionOrderUpdateDTO, boolean verifyExcutorAuth);

    /**
     * 保存并提交
     *
     * @param excutionOrderUpdateDTO
     * @param isConfirm
     * @return Integer
     */
    boolean saveAndSubmit(ExcutionOrderUpdateDTO excutionOrderUpdateDTO, boolean isConfirm);

    /**
     * 保存并提交
     *
     * @param excutionOrderUpdateDTO ExcutionOrderUpdateDTO
     */
    void saveAndComplete(ExcutionOrderUpdateDTO excutionOrderUpdateDTO);

    /**
     * 执行单列表
     *
     * @param mcnPage                McnPage<ExcutionOrderVO>
     * @param excutionOrderSearchDTO ExcutionOrderSearchDTO
     * @return Page<ExcutionOrderVO>
     */
    Page<ExcutionOrderVO> getPage(McnPage<ExcutionOrderVO> mcnPage, ExcutionOrderSearchDTO excutionOrderSearchDTO);

    /**
     * 导出执行单
     *
     * @param excutionOrderSearchDTO
     * @return
     */
    List<ExcutionExportVO> export(ExcutionOrderSearchDTO excutionOrderSearchDTO);


    /**
     * 系系统计算分成金额
     *
     * @param contractExcutionOrder
     * @param calculationDevided
     * @return
     */
    BigDecimal getSysDevidedAmount(ContractExcutionOrder contractExcutionOrder, CalculationDevided calculationDevided);

    /**
     * 获取年度优惠返点比例
     *
     * @param contractExcutionOrder ContractExcutionOrder
     * @return BigDecimal
     */
    BigDecimal getYearRebateRate(ContractExcutionOrder contractExcutionOrder);

    /**
     * 修改单据状态
     *
     * @param statusDTO
     * @param fromController   {@link String}
     * @return {@link Res <Object>}
     */
    boolean changeStatus(ExcutionOrderChangeStatusDTO statusDTO, boolean fromController);

    /**
     * 回调已打款
     * @param paidCallback
     * @return
     */
    Boolean setPaid(ExcutionOrderPaidCallback paidCallback);

    /**
     * 审批流财务确认分成金额
     *
     * @param checkParam CheckParam
     * @return Boolean
     */
    Boolean shareAmount(CheckParam checkParam);

    /**
     * 财务结算单的执行单信息
     *
     * @param chargeType
     * @param chargeSourceCode
     * @return {@link ExcutionSettleInfoVO}
     */
    ExcutionSettleInfoVO getSettleInfoForCharge(Integer chargeType, String chargeSourceCode);

    /**
     * 根据id获取执行单
     *
     * @param id
     * @return ContractExcutionOrder
     */
    ContractExcutionOrder getById(Long id);

    /**
     * 客户关联的执行单信息
     *
     * @param customerId
     * @param mcnPage
     * @return
     */
    Page<CusExcutionOrderVO> getCusExcutionOrder(McnPage<CusExcutionOrderVO> mcnPage, Long customerId);

    /**
     * 根据执行单号获取执行单总金额
     *
     * @param executeCode 执行单号
     * @return {@link BigDecimal}
     */
    BigDecimal getActualQuotedPrice(String executeCode);

    /**
     * 通过执行单编号获取详情
     *
     * @param executeCode
     * @return
     */
    ContractExcutionOrder getByCode(String executeCode);

    /**
     * 供AE提成单查询执行单列表
     *
     * @param mcnPage
     * @param excutionOrderSearchDTO
     * @return Page<ExcutionOrderVO>
     */
    Page<ExcutionOrderVO> getAePage(McnPage<ExcutionOrderVO> mcnPage, ExcutionOrderSearchDTO excutionOrderSearchDTO);

    /**
     * 导出弹框分页查询-提成数据
     * @param excutionOrderSearchDTO
     */
    List<ExcutionOrderVO> getExportCommissionData(ExcutionOrderSearchDTO excutionOrderSearchDTO);

    /**
     * 供红人返点合同使用
     *
     * @param mcnPage
     * @param excutionOrderSearchDTO
     * @return Page<StarRebateExcutionOrderVO>
     */
    Page<StarRebateExcutionOrderVO> getStarRebatePage(McnPage<ExcutionOrderVO> mcnPage, ExcutionOrderSearchDTO excutionOrderSearchDTO);

    /**
     * 供客户返点合同使用
     *
     * @param mcnPage
     * @param excutionOrderSearchDTO
     * @return Page<StarRebateExcutionOrderVO>
     */
    Page<AnnualRebateExcutionOrderVO> getAnnualRebatePage(McnPage<ExcutionOrderVO> mcnPage, ExcutionOrderSearchDTO excutionOrderSearchDTO);

    /**
     * 供AE提成单查询执行单列表
     *
     * @param aeQueryExcutionOrderDTO
     * @return
     */
    List<Long> getContractExcutionOrderByCondition(AeQueryExcutionOrderDTO aeQueryExcutionOrderDTO);

    /**
     * 批量查询执行单
     *
     * @param ids
     * @return
     */
    List<ContractExcutionOrder> getAllByIds(List<Long> ids);

    /**
     * 批量更新执行单提成结算状态
     *
     * @param excutionOrderIds       执行单id集合
     * @param commissionSettleStatus 提成结算状态：0:未结算；1:结算中；2:已结算
     * @return Integer
     */
    Integer batchUpdateSettleStatus(List<Long> excutionOrderIds, Integer commissionSettleStatus);

    /**
     * 校验形式类合同-执行单
     *
     * @param contractId
     * @param isFromExcutionOrder
     * @param excutionOrders
     */
    void verifyFormalExcutionOrder(Long contractId, boolean isFromExcutionOrder, List<ContractExcutionOrder> excutionOrders);

    /**
     * 校验平台订单号
     * @param contractId
     * @param excutionOrders
     */
    void verifyPlatformOrderNumber(Long contractId, List<ContractExcutionOrder> excutionOrders);

    /**
     * 执行单变更打款回调
     *
     * @param changePaidCallback
     * @return
     */
    @Deprecated
    Boolean changePaidCallback(ExcutionOrderChangePaidCallback changePaidCallback);

    /**
     * 收入合同(补充协议）修改时，同步变更执行单
     *
     * @param contractId
     * @param excutionOrders
     */
    void changeExcutionOrders(Long contractId, List<ContractExcutionOrder> excutionOrders);

    /**
     * 获取产品名称
     *
     * @return {@link List<String>}
     */
    List<String> getProductName();

    /**
     * 导入Excel-财务批量确认
     * @param inputList {@link List<   ExcutionOrderBatchConfirmInputDTO   >}
     * @return String
     */
    String financeBatchConfirm(List<ExcutionOrderBatchConfirmInputDTO> inputList);

    /**
     * 导入Excel-批量审批
     * @param inputList
     * @return
     */
    String financeBatchApproval(List<ExcutionOrderBatchApprovalInputDTO> inputList);


    /**
     * 下载失败原因
     *
     * @param response {@link HttpServletResponse}
     * @param fileId
     */
    void excelDownload(HttpServletResponse response, String fileId);


    /**
     * 获取执行单计算分成关联的年框合同
     *
     * @return 年框合同
     */
    List<StarPurchaseYearFrameVO> getStarPurchaseContract();

    /**
     * 获取执行单计算分成关联的采购合同
     *
     * @param incomeContractId 收入合同id
     * @return 采购合同
     */
    List<AssociatedPurchase> getPurchaseContract(Long incomeContractId);

    /**
     * 根据红人返点合同选择的年框合同编号获取关联的执行单信息
     *
     * @param yearContractCode
     * @return
     */
    List<StarRebateExcutionOrderVO> getByYearCodeOfStarRebate(String yearContractCode);

    /**
     * 是否关联采购单号
     *
     * @param state        状态（0-否，1-是）
     * @param contractCode 执行单单号
     * @return 采购单号
     */
    String getPurchaseContractCode(Integer state, String contractCode);

    /**
     * koc批量导入
     * @param multipartFile
     * @return
     */
    String kocBatchImport(MultipartFile multipartFile);

    /**
     * 下载KOC导入失败原因
     * @param response
     */
    void kocBatchOutput(HttpServletResponse response);

    /**
     * 通过执行单ID强制驳回执行单
      * @param id
     * @return
     */
    boolean forcedReject(Long id);

    /**
     * 批量确认打款
     * @param dto
     * @return
     */
    BatchConfirmPaidResultVO batchConfirmPaid(BatchConfirmPaidDTO dto);

    /**
     * 通过执行单编号获取财务执行单信息
     * @param excuteCodes
     * @return
     */
    List<FinanceExcutionOrderVO> getFinanceExcutionOrderByCodes(List<String> excuteCodes);

    /**
     * 动态选择导出字段
     * @param exportTypeStr
     * @return
     */
    List<ExcelCustom> chooseExportField(String exportTypeStr);


    /**
     * 执行单-回款
     * @param dto
     * @param excutionOrder
     * @param totalAmount
     * @param needUpdatePaid
     * @return 差额
     */
    void updatePayback(ChargeClearCallback dto, ContractExcutionOrder excutionOrder, BigDecimal totalAmount, boolean needUpdatePaid);

    /**
     * 根据执行单ID批量更新结算状态
     * @param excuteIds
     * @param sourceStatus
     * @param targetStatus
     */
    void updateBusinessCommissionSettleStatusByIds(List<Long> excuteIds, Integer sourceStatus, Integer targetStatus);

    /**
     * 获取批量提交/审批数据
     * @param executeIds
     * @param allowStatusEnum
     */
    List<ExcutionOrderUpdateDTO> getBatchSubmitData(List<Long> executeIds, ExcutionApprovalStatusEnum allowStatusEnum);

    /**
     * 更新红人分成比例及系统参考分成
     * @param excuteId
     * @param realPublishDate
     * @param needUpdate
     * @return
     */
    DividedRateOrSysAmountVO getOrUpdateDividedRate(Long excuteId, Date realPublishDate, boolean needUpdate);

}